﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Threading.Tasks;
using DotNetCore.CAP;
using Microsoft.Extensions.Logging;
using ZhonTai.Admin.Core.Attributes;
using ZhonTai.Industry.Contracts.Model.Dic;
using ZhonTai.Industry.Contracts.Model.Entity;
using ZhonTai.Industry.Core.Consts;
using ZhonTai.Industry.Core.Core.CraftGather.BatchSave;
using ZhonTai.Industry.Core.Core.DeviceMutual;
using ZhonTai.Industry.Core.CraftGather.Query;
using ZhonTai.Industry.Core.CraftGather.Save;
using ZhonTai.Industry.Core.Service.MessageHandler;
using ZhonTai.Industry.Core.Service.MessageHandler.CraftGather;
using ZhonTai.Industry.Core.Service.MessageHandler.RecipeMonitor;

namespace ZhonTai.Industry.Core.Core.Common
{
    /// <summary>
    /// 消息处理器
    /// </summary>
    [InjectSingleton]
    public class SubHandler : ICapSubscribe
    {
        private readonly ILogger<SubHandler> _logger;
        private readonly Dictionary<string, IMessageHandler> _handlers;

        public SubHandler(
            ILogger<SubHandler> logger
            , QueryHandle queryHandle
            , SaveHandle saveHandle
            , FormulaHandle formulaHandle
            , BatchSaveHandle batchSaveHandle)
        {
            _logger = logger;
            _handlers = new Dictionary<string, IMessageHandler>(StringComparer.Ordinal)
            {
                [OffsetConsts.ReqQuery] = new QueryMessageHandler(queryHandle)
                ,
                [OffsetConsts.ReqSave] = new SaveMessageHandler(saveHandle)
                ,
                [OffsetConsts.ReqFormula] = new RecipeMonitorHandler(formulaHandle)
                ,
                [OffsetConsts.ReqBatch1] = new BatchSaveMessageHandler(batchSaveHandle)
                ,
                [OffsetConsts.ReqBatch2] = new BatchSaveMessageHandler(batchSaveHandle)
                ,
                [OffsetConsts.ReqBatch3] = new BatchSaveMessageHandler(batchSaveHandle)
                ,
                [OffsetConsts.ReqBatch4] = new BatchSaveMessageHandler(batchSaveHandle)
                ,
                [OffsetConsts.ReqBatch5] = new BatchSaveMessageHandler(batchSaveHandle)
            };
        }

        /// <summary>
        /// 消息处理
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        [CapSubscribe("ProcessMonitor")]
        public async Task HandleMessageAsync(PushShip message)
        {
            try
            {
                _ = Task.Run(async () =>
                 {
                     message.Example = InstanceDic.ProcessDic[message.StationId];
                     if (await TryResetFieldsAsync(message))
                     {
                         return;
                     }

                     if (ShouldTriggerOperation(message))
                     {
                         await ProcessMessageCoreAsync(message);
                     }
                 });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "消息处理失败");
                throw;
            }
        }

        private async Task<bool> TryResetFieldsAsync(PushShip message)
        {
            if (!IsResetConditionMet(message.Value)) return false;
            var resetFields = message.Example._mesDB.DataFields
                .FindAll(x => x.GroupName == message.GroupName);

            foreach (var field in resetFields)
            {
                await message.Example.WriteAsync(field.Offset, (short)0, message.Example._ship.MESDB.DBAddress);
            }
            return true;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private bool IsResetConditionMet(object value)
        {
            if (value is JsonElement element)
            {
                return element.ValueKind switch
                {
                    JsonValueKind.Number => element.TryGetInt32(out int intVal) && intVal == 0,
                    JsonValueKind.False => true,
                    JsonValueKind.String => IsZeroString(element),
                    _ => false
                };
            }
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private bool ShouldTriggerOperation(PushShip message)
        {
            if (message.Value is JsonElement element)
            {
                return element.ValueKind switch
                {
                    JsonValueKind.Number => element.TryGetInt32(out int intVal) && intVal > 0,
                    JsonValueKind.True => true,
                    JsonValueKind.String => IsOneString(element),
                    _ => false
                };
            }
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool IsZeroString(JsonElement element)
        {
            return element.GetString() switch
            {
                "0" => true,
                "false" => true,
                _ => false
            };
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool IsOneString(JsonElement element)
        {
            return element.GetString() switch
            {
                "1" => true,
                "true" => true,
                _ => false
            };
        }

        private async Task ProcessMessageCoreAsync(PushShip message)
        {
            if (_handlers.TryGetValue(message.Another, out var handler))
            {
                await handler.HandleAsync(message);
            }
            else
            {
                _logger.LogWarning($"未注册的处理器类型：{message.Another}");
            }
        }
    }
}